#ifndef VSDX9RENDERER_H
#define VSDX9RENDERER_H
#ifdef VSDX9RENDERER_EXPORTS
#define  VSDX9RENDERER_API __declspec(dllexport) 
#else
#define  VSDX9RENDERER_API __declspec(dllimport)
#endif
#include <d3d9.h>
#include <d3dx9tex.h>
#include <dxerr9.h>
#include "VSRenderer.h"
#include "VSDx9Command.h"
#include "VSResourceManager.h"
namespace VSEngine2
{
	#define VSMAC_RELEASE(p)      { if(p) { (p)->Release(); (p)=NULL; } }
	class VSDx9ShaderInclude;
	class VSDX9RENDERER_API VSDX9Renderer : public VSRenderer
	{
	public:
		VSDX9Renderer(HWND hMainWindow,unsigned int uiScreenWidth,unsigned int uiScreenHeight,bool bIsWindowed,
					unsigned int uiAnisotropy,unsigned int uiMultisample,
					ChildWindowInfo * pChildWindow,int uiNumChildWindow);
		virtual ~VSDX9Renderer();
		virtual int GetRendererType () const;
		
		virtual void ClearBackBuffer ();
		virtual void ClearZBuffer ();
		virtual void ClearStencilBuffer ();
		virtual void ClearBuffers ();
		virtual void ClearBuffers(unsigned int uiClearFlag);
		//virtual void DisplayBackBuffer ();
		virtual void DeviceLost();
		virtual void ResetDevice();
		virtual bool ChangeScreenSize(unsigned int uiWidth,unsigned int uiHeight,bool bWindow);

		virtual void ClearBackBuffer (int iXPos, int iYPos, int iWidth,
			int iHeight);
		virtual void ClearZBuffer (int iXPos, int iYPos, int iWidth,
			int iHeight);
		virtual void ClearStencilBuffer (int iXPos, int iYPos, int iWidth,
			int iHeight);
		virtual void ClearBuffers (int iXPos, int iYPos, int iWidth,
			int iHeight);
		virtual void ClearBuffers(unsigned int uiClearFlag,int iXPos, int iYPos, int iWidth,
			int iHeight);
		virtual void OnDrawText(int iX, int iY, const VSColorRGBA& rColor,VSString & String);
		virtual unsigned int GetTextureCompressLen(unsigned int uiLen);
		
		static const VSAdapterInfo* GetAdapterInfo(unsigned int & uiAdapterNum);

		virtual bool CooperativeLevel();
		virtual bool BeginRendering();
		virtual bool EndRendering();
		virtual bool DrawMesh(VSGeometry * pGeometry,VSRenderState * pRenderState,VSVShader * pVShader, VSPShader * pPShader);
		virtual bool DrawScreen(SCREEN_QUAD_TYPE ScreenQuad[4]);
		virtual bool DrawScreen(SCREEN_QUAD_TYPE * pScreenBuffer,unsigned int uiVertexNum,
								VSUSHORT_INDEX * pIndexBuffer,unsigned int uiIndexNum);
	protected:
		
// 		virtual bool SetVProgramConstant (VSString &NameInShaderProgram,void * pDate,unsigned int uiSize);
// 		virtual bool SetPProgramConstant (VSString &NameInShaderProgram,void * pDate,unsigned int uiSize);
		virtual bool SetVProgramConstant (unsigned int uiStartRegister,void * pDate,
											unsigned int RegisterNum,unsigned int uiType);
		virtual bool SetPProgramConstant (unsigned int uiStartRegister,void * pDate,
											unsigned int RegisterNum,unsigned int uiType);
		//Load Release
		virtual bool OnLoadVShaderProgram (VSVShader * pVShaderProgram,VSResourceIdentifier *&pID);
		virtual bool OnReleaseVShaderProgram(VSResourceIdentifier * pVShaderProgramID);

		virtual bool OnLoadPShaderProgram (VSPShader* pPShaderProgram,VSResourceIdentifier *&pID);
		virtual bool OnReleasePShaderProgram (VSResourceIdentifier* pPShaderProgramID);

		virtual bool OnLoadTexture (VSTexture * pTexture,VSResourceIdentifier *&pID);
		virtual bool OnReleaseTexture (VSResourceIdentifier * pTextureID);

		virtual bool OnLoadDepthStencil (VSDepthStencil * pDepthStencil,VSResourceIdentifier *&pID);
		virtual bool OnReleaseDepthStencil (VSResourceIdentifier * pDepthStencilID);
		
		virtual bool OnLoadRenderTarget (VSRenderTarget * pRenderTarget,VSResourceIdentifier *&pID);
		virtual bool OnReleaseRenderTarget (VSResourceIdentifier * pRenderTarget);

		virtual bool OnLoadVBufferDate (VSVertexBuffer * pVBuffer,VSResourceIdentifier *&pID);
		virtual bool OnReleaseVBufferDate (VSResourceIdentifier* pVBufferID);

		virtual bool OnLoadVBufferFormat (VSVertexFormat * pVertexFormat,VSResourceIdentifier *&pID);
		virtual bool OnReleaseVBufferFormat (VSResourceIdentifier* pVBufferID);

		virtual bool OnLoadIBuffer (VSIndexBuffer* pIBuffer,VSResourceIdentifier *&pID);
		virtual bool OnReleaseIBuffer (VSResourceIdentifier* pIBufferID);

		virtual bool OnLoadFont(VSFont * pFont, VSResourceIdentifier *&pID);
		virtual bool OnReleaseFont(VSResourceIdentifier * pFontID);

		virtual bool OnLoadBlendState (VSBlendState * pBlendState,VSResourceIdentifier *&pID);
		virtual bool OnReleaseBlendState  (VSResourceIdentifier * pBlendStateID);

		virtual bool OnLoadDepthStencilState (VSDepthStencilState * pDepthStencilState,VSResourceIdentifier *&pID);
		virtual bool OnReleaseDepthStencilState  (VSResourceIdentifier * pDepthStencilStateID);

		virtual bool OnLoadRasterizerState(VSRasterizerState * pRasterizerState,VSResourceIdentifier *&pID);
		virtual bool OnReleaseRasterizerState  (VSResourceIdentifier * pRasterizerStateID);

		virtual bool OnLoadSamplerState(VSSamplerState * pRasterizerState,VSResourceIdentifier *&pID);
		virtual bool OnReleaseSamplerState  (VSResourceIdentifier * pRasterizerStateID);

		virtual bool SetVShaderProgram(VSVShader*	pVShaderProgram);
		virtual bool SetPShaderProgram (VSPShader*pPShaderProgram);

		virtual void * Lock(VSVertexBuffer * pVertexBuffer);
		virtual void UnLock(VSVertexBuffer * pVertexBuffer);

		virtual void * Lock(VSIndexBuffer * pIndexBuffer);
		virtual void UnLock(VSIndexBuffer * pIndexBuffer);

		virtual void * Lock(VSTexture * pTexture,unsigned int uiLevel,unsigned int uiFace);
		virtual void UnLock(VSTexture * pTexture,unsigned int uiLevel,unsigned int uiFace);

		virtual unsigned int SetVertexFormat(VSVertexFormat * pVertexFormat);
		virtual bool CopyResourceBuffer(VS2DTexture * pSource,VSCubeTexture * pDest,unsigned int uiFace);
		void SetVShaderConstant(VSVShader * pShader);
		void SetVShaderSampler(VSVShader * pShader);
		void SetPShaderConstant(VSPShader * pShader);
		void SetPShaderSampler(VSPShader * pShader);

		D3DXMACRO * GetDefine(VSMap<VSString,VSString> & Define);
	private:
// 		DX9_API_FUN_TWOPARAMETER(SetRenderState,D3DRENDERSTATETYPE,State,DWORD,Value)
// 		DX9_API_FUN_END
 		bool SetRenderState(D3DRENDERSTATETYPE State,DWORD Value);
 		bool SetSamplerState(DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD Value);
		bool Clear(DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil);
		bool SetClipPlane(DWORD Index,CONST float* pPlane);
		bool SetScissorRect(CONST RECT* pRect);
		bool SetVertexShader(IDirect3DVertexShader9* pShader);
		bool SetPixelShader(IDirect3DPixelShader9* pShader);
		bool SetTexture(DWORD Stage,IDirect3DBaseTexture9* pTexture);
		bool SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride);
		bool SetVertexDeclaration(IDirect3DVertexDeclaration9* pDecl);
		bool SetIndices(IDirect3DIndexBuffer9* pIndexData);
		bool SetViewport(CONST D3DVIEWPORT9* pViewport);
		bool SetVertexShaderConstant(unsigned int uiStartRegister,void * pDate,
									unsigned int RegisterNum,unsigned int uiType);
		bool SetPixelShaderConstant(unsigned int uiStartRegister,void * pDate,
			unsigned int RegisterNum,unsigned int uiType);
		bool DrawDynamicBufferMesh(VSDynamicBufferGeometry *pDBGeometry);
		bool DrawMesh(VSGeometry * pGeometry);
		bool DrawMesh1(VSGeometry * pGeometry);
		bool DrawScreenEX2(SCREEN_QUAD_TYPE * pScreenBuffer,unsigned int uiVertexNum,
			VSUSHORT_INDEX * pIndexBuffer,unsigned int uiNumTri);
		bool DrawScreenEX1(SCREEN_QUAD_TYPE ScreenQuad[4]);
		bool SetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9* pRenderTarget);
		bool GetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9** ppRenderTarget);
		bool SetDepthStencilSurface(IDirect3DSurface9* pNewZStencil);
		bool GetDepthStencilSurface(IDirect3DSurface9** ppZStencilSurface);
		bool SetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9* pRenderTarget,IDirect3DSurface9** ppRenderTarget);
		bool EndRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9** pRenderTarget);
		bool SetDepthStencilSurface(IDirect3DSurface9* pNewZStencil,IDirect3DSurface9** ppZStencilSurface);
		bool EndDepthStencilSurface(IDirect3DSurface9** pNewZStencil);
		bool StretchRect(IDirect3DSurface9* pSourceSurface,CONST RECT* pSourceRect,IDirect3DSurface9* pDestSurface,CONST RECT* pDestRect,D3DTEXTUREFILTERTYPE Filter);
		bool BeginRender();
		bool EndRender();
		bool UseWindowEx(int uiWindowID);
		bool DrawText(LPD3DXFONT pFont,int iX, int iY, const VSColorRGBA& rColor,VSString & String);
	public:
		//Enable Disable
		
		virtual unsigned int SetVShader(VSVShader * pVShader);
		virtual unsigned int SetPShader(VSPShader * pPShader);
		virtual unsigned int SetVBuffer(VSVertexBuffer * pVBuffer);
		virtual unsigned int SetIBuffer (VSIndexBuffer * pIBuffer);
		virtual unsigned int SetTexture (VSTexture* pTexture,unsigned int i);
		virtual unsigned int SetVTexture (VSTexture* pTexture,unsigned int i);

		virtual unsigned int SetSamplerState(VSSamplerState * pSamplerState,unsigned int i);
		virtual unsigned int SetBlendState(VSBlendState * pBlendState);
		virtual unsigned int SetDepthStencilState(VSDepthStencilState * pDepthStencilState);
		virtual unsigned int SetRasterizerState(VSRasterizerState * pRasterizerState);
		virtual void SetClipPlane(VSArray<VSPlane3> &Plane,bool bEnable);
		virtual void SetScissorRect(VSArray<VSRect2> &Rect,bool bEnable);

		virtual bool SetRenderTarget(VSRenderTarget *pRenderTarget,unsigned int i);
		virtual bool EndRenderTarget(VSRenderTarget *pRenderTarget,unsigned int i);
		virtual bool SetDepthStencilBuffer(VSDepthStencil * pDepthStencilBuffer);
		virtual bool EndDepthStencilBuffer(VSDepthStencil * pDepthStencilBuffer);
		virtual bool SetViewPort(VSCamera * pCamera,unsigned int i = 0);

		virtual bool UseWindow(int uiWindowID);
		

	protected:
		
		static VSDx9ShaderInclude * ms_pDx9IncludeShader;
		static HRESULT ms_hResult;
		static LPDIRECT3D9 ms_pMain;
		LPDIRECT3DDEVICE9 m_pDevice;
		LPDIRECT3DSWAPCHAIN9  * m_pChain;	
		LPDIRECT3DSWAPCHAIN9  m_pMainChain;
		D3DPRESENT_PARAMETERS m_Present;

		LPDIRECT3DSURFACE9	m_pMainDepthStencilBuffer;
		LPDIRECT3DSURFACE9*	m_pChainnDepthStencilBuffer;

		DWORD		 m_dwMultisampleQuality;
		static DWORD ms_dwAlphaBlend[];
		static DWORD ms_dwAlphaBlendOP[];
		static DWORD ms_dwCullType[];
		static DWORD ms_dwAlphaTest[];

		static DWORD ms_dwFogComputeMethod[];


		static DWORD ms_dwStencilOperation[];

		static DWORD ms_dwCompare[];

		static DWORD ms_dwTextureFormatType[];
		static DWORD ms_dwTextureFilterType[];
		static DWORD ms_dwTextureAddrType[];


		static DWORD ms_dwLightType[];
		static DWORD ms_dwPrimitiveType[];
		static DWORD ms_dwDevTypes[]; 
		static DWORD ms_dwMultiSampleTypes[]; 
		static DWORD ms_dwCubeMapFace[];
		static DWORD ms_dwLockFlag[];
		static DWORD ms_dwVertexFormatDateType[];
		static DWORD ms_dwVertexFormatSemantics[];

		static unsigned int ms_uiVertexShaderProgramVersion;
		static unsigned int ms_uiPixelShaderProgramVersion;
		static TCHAR ms_cVertexShaderProgramVersion[];
		static TCHAR ms_cPixelShaderProgramVersion[];

		enum
		{
			MAX_SHADER_BUFFER = 1024,
			MAX_TEXTURE_BUFFER = 16
		};
		VSREAL	m_fFloatShaderBuffer[MAX_SHADER_BUFFER];
		int		m_iIntShaderBuffer[MAX_SHADER_BUFFER];
		bool	m_bBoolShaderBuffer[MAX_SHADER_BUFFER];
		VSTexAllState * m_pTexAllStateBuffer[MAX_TEXTURE_BUFFER];
		//PRIORITY
		DECLARE_PRIORITY
	public:
		static bool RegisterMainFactory();
	private:
		static bool ms_bRegisterMainFactory;
		static bool InitialDefaultState();
		static bool TerminalDefaultState();

	public:
		//function in d3d  so output is string
		virtual VSString Tex2D(const VS2DTexSampler * p2DTexSampler) const;
		//
		virtual VSString Sampler(unsigned int uiType)const;
		virtual VSString Float()const;
		virtual VSString Float2()const;
		virtual VSString Float3()const;
		virtual VSString Float4()const;

		virtual VSString FloatConst(const VSString & Value1)const;
		virtual VSString Float2Const(const VSString & Value1,const VSString & Value2)const;
		virtual VSString Float3Const(const VSString & Value1,
			const VSString & Value2,const VSString & Value3)const;
		virtual VSString Float4Const(const VSString & Value1,const VSString & Value2,
			const VSString & Value3,const VSString & Value4)const;
		virtual VSString SetRegister(unsigned int uiRegisterType,unsigned int uiRegisterIndex)const;
		virtual VSString GetValueElement(const VSPutNode * pPutNode,
										unsigned char uiVE)const;



		virtual void CreateVInputDeclare(MaterialShaderPara1 &MSPara1,unsigned int uiPassType,
										VSString & OutString);
		virtual void CreateVOutputDeclare(MaterialShaderPara1 &MSPara1,unsigned int uiPassType,
										VSString & OutString);
		virtual void CreateVUserConstant(VSVShader * pVShader,MaterialShaderPara1 &MSPara1,unsigned int uiPassType,
										VSString & OutString);
		virtual void CreateVFuntion(MaterialShaderPara1 &MSPara1,unsigned int uiPassType,
									VSString & OutString);	
		virtual void SetMaterialVShaderConstant(MaterialShaderPara1 &MSPara1,unsigned int uiPassType,VSVShader *pVShader);


		virtual void CreatePInputDeclare(MaterialShaderPara1 &MSPara1,unsigned int uiPassType,
										VSString & OutString);
		virtual void CreatePOutputDeclare(MaterialShaderPara1 &MSPara1,unsigned int uiPassType,
										VSString & OutString);
		virtual void CreatePUserConstant(VSPShader* pPShader,MaterialShaderPara1 &MSPara1,unsigned int uiPassType,
										VSString & OutString);
		virtual void CreatePFuntion(MaterialShaderPara1 &MSPara1,unsigned int uiPassType,
									VSString & OutString);	
		virtual void SetMaterialPShaderConstant(MaterialShaderPara1 &MSPara1,unsigned int uiPassType,VSPShader *pPShader);


		/************************************************************************************/
		//fun is custorm output is paramter
		virtual void DirectionalLight(int iLightNum,const VSString &Diffuse,const VSString &Specular ,const VSString &SpecularPow,
			const VSString &WorldNormal,const VSString &WorldCameraDir,VSString & OutString)const;
		virtual void OrenNayarDirectionalLight(int iLightNum,const VSString &Diffuse,const VSString &Specular ,const VSString &SpecularPow,
					const VSString &WorldNormal,const VSString &WorldCameraDir,bool bLookUpTable,
					VSString & OutString)const;
		virtual void PointLight(int iLightNum,const VSString &Diffuse,const VSString &Specular ,const VSString &SpecularPow,
								const VSString & WorldPos,const VSString &WorldNormal,const VSString &WorldCameraDir,
								VSString & OutString)const;

		virtual void SpotLight(int iLightNum,const VSString &Diffuse,const VSString &Specular ,const VSString &SpecularPow,
								const VSString & WorldPos,const VSString &WorldNormal,const VSString &WorldCameraDir,
								VSString & OutString)const;

		virtual void ProjLight(int iLightNum,const VSString &Diffuse,const VSString & WorldPos,const VSString &WorldNormal,
			VSString & OutString)const;

		virtual void LocalToWorldPos(const VSString & LocalPos,VSString &OutString)const;

		virtual void LocalToWorldNormal(const VSString & LocalNormal,VSString &OutString)const;

		virtual void BumpNormal(const VSString &TexNormal,VSString &OutString)const;

		virtual void ComputeDir(const VSString & Orgin,const VSString & End,VSString &OutString)const;

		virtual void GetLightType(unsigned int i,VSString &OutString)const;
		virtual void ComputeBoneVector(const VSString& BoneIndex, const VSString & BoneWeight,const VSString &BoneVector,
			 const  VSString & U,const VSString & V,const VSString &N,VSString &OutString)const;

		virtual void BoneTranPos( const VSString & LocalPos,const  VSString & U,const VSString & V,const VSString &N,VSString &OutString)const;
		virtual void BoneTranNormal( const VSString & LocalNormal,const  VSString & U,const VSString & V,const VSString &N,VSString &OutString)const;

		virtual void DecodeNormal1(const VSString & Normal,VSString &OutString) const;
		virtual void RecodeNormal1(const VSString & Normal,VSString &OutString) const;
		virtual void DecodeNormal2(const VSString & Normal,const VSString & Tengent,VSString &OutString) const;
		virtual void DecodeNormal3(const VSString & Normal,VSString &OutString) const;
		virtual void RecodeNormal3(const VSString & Normal,VSString &OutString) const;

		virtual void GreaterZeroPow(const VSString & Value,float Exp,VSString &OutString) const;
		virtual void SaturatePow(const VSString & Value,float Exp,VSString &OutString) const;
	};


}
#endif